package tarea2.managedbeans;

import entidades.Administrador;
import entidades.Administrativo;
import entidades.Cita;
import entidades.ListaDeEspera;
import entidades.Medico;
import entidades.Mensaje;
import entidades.Paciente;
import entidades.Usuario;
import java.util.ArrayList;
import java.sql.Date;
import java.util.List;
import java.util.Locale;
import javax.enterprise.context.ApplicationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

@Named(value = "login")
@ApplicationScoped
public class LoginMBean {

    private String dni;
    private String nombre;
    private String contrasena;
    private String apellidos;
    private int year, mes, dia;
    private Date fecha;
    private String email;
    private String telefono;
    private String especialidad;
    private int numeroTrabajador;
    private String departamento;
    private int yearC, mesC, diaC, horC, minC;
    private String lugar;
    private String motivo;
    private boolean urgente;
    private List<Cita> citas = new ArrayList<>();
    private int med;
    private int pac;
    private String tipo;
    private List<String> mdni = new ArrayList<>();
    private List<String> pdni = new ArrayList<>();
    private List<Medico> medicos = new ArrayList<>();
    private List<Paciente> pacientes = new ArrayList<>();
    private List<Administrador> administrador = new ArrayList<>();
    private List<Administrativo> administrativos = new ArrayList<>();
    private String nombreL;
    private int listaE;
    private List<ListaDeEspera> lista = new ArrayList<>();
    @Inject
    private UsuarioMBean usuarioMBean;

    public LoginMBean() {
        //Usuarios Iniciales
        Medico medico = new Medico("12345678Z", "pass",
                "Dr. Pablo", "Gonzales Miercoles", Date.valueOf("1975-11-23"), "email@email.com", "123456789",
                "Cardiologo", 12345, "Cardiologia");
        Administrativo administrativo = new Administrativo("12345678W", "pass", "Francisco", "lopez",
                Date.valueOf("1990-03-01"), "email@email.com", "123456789", 234, "reciclaje");
        Paciente paciente = new Paciente("12345678X", "pass",
                "Samuel", "Lehotsky", Date.valueOf("1990-03-01"), "email@email.com", "123456789", "123456789");

        pacientes.add(paciente);
        medicos.add(medico);
        administrativos.add(administrativo);

        Mensaje mensaje1 = new Mensaje(1L, Mensaje.Tipo.mensaje, "Hola Paciente", medico, paciente);
        Mensaje mensaje2 = new Mensaje(2L, Mensaje.Tipo.mensaje, "Hola Doctor", paciente, medico);
        Mensaje mensaje3 = new Mensaje(3L, Mensaje.Tipo.mensaje, "Una muy larga oracion."
                + " Lorem ipsum dolor sit"
                + " amet, consectetur adipiscing elit. Aliquam a orci est. Suspendisse eros dui, semper qu"
                + "is lobortis ac, placerat vitae ligula. Praesent vehicula feugiat imperdiet. Ut aliquet he"
                + "ndrerit velit, sit amet faucibus dui tempus eu. Fusce id molestie libero. Sed hendrerit p"
                + "osuere dolor, eget sollicitudin turpis sodales nec. Aenean vel ornare libero, vitae eleme"
                + "ntum massa. Donec vehicula pulvinar mauris, ut pretium urna dapibus in. Nullam faucibus a"
                + "t metus ac facilisis.\n"
                + "\n"
                + "Praesent elementum nisl arcu, et tristique eros porttitor egestas. Sed porta ante id lacus accumsan volutpat."
                + "Ut ut diam quis orci sollicitudin commodo eget nec tellus. Phasellus quis urna eget "
                + "nisi laoreet congue. Suspendisse tempor gravida vulputate. Nullam id aliquam eros, interdum "
                + "pulvinar enim. Quisque consectetur ullamcorper arcu vitae consequat. Vivamus molestie ultrices"
                + " dapibus. Ut ornare dui eu mi pharetra venenatis. Etiam feugiat leo diam, a vehicula ligula ve"
                + "stibulum a. Praesent tortor urna, vulputate sit amet tristique eget, pellentesque et nisi. Pelle"
                + "ntesque quis tortor eget nisl tempus aliquet vitae nec metus. Pellentesque varius, nisl in tempor fe"
                + "rmentum, magna nisi sagittis dui, vitae iaculis libero orci sed ipsum. Nunc nec laoreet ante. Nu"
                + "lla pellentesque facilisis rhoncus. Aenean nec nisi leo.", medico, paciente);
        Mensaje queja = new Mensaje(4L, Mensaje.Tipo.queja, "El doctor es terible, no le quiero", paciente, null);
        Mensaje alerta = new Mensaje(5L, Mensaje.Tipo.alerta, "Su resultados de sangre son preparados", medico, paciente);

        paciente.setEnviados(new ArrayList<Mensaje>());
        paciente.getEnviados().add(mensaje2);
        paciente.getEnviados().add(queja);

        medico.setRecibidos(new ArrayList<Mensaje>());
        medico.getRecibidos().add(mensaje2);

        medico.setEnviados(new ArrayList<Mensaje>());
        medico.getEnviados().add(mensaje1);
        medico.getEnviados().add(mensaje3);
        medico.getEnviados().add(alerta);

        paciente.setRecibidos(new ArrayList<Mensaje>());
        paciente.getRecibidos().add(mensaje1);
        paciente.getRecibidos().add(mensaje3);
        paciente.getRecibidos().add(alerta);



        Administrador adm = new Administrador("11111111A", "1", "Juan", "Manuel",
                Date.valueOf("1995-03-01"), "Samuel@gmail.com", "444555666", 0);
        administrador.add(adm);

        Medico med1 = new Medico("22222222B", "2", "Cristina", "Fernandez",
                Date.valueOf("1998-03-01"), "luis@hotmail.com", "123456789", "Something", 0, null);
        medicos.add(med1);

        Medico med2 = new Medico("33333333C", "3", "Miguel", "Hernandez",
                Date.valueOf("1975-03-01"), "Pablo@yahoo.com", "987654321", null, 0, null);
        medicos.add(med2);

        Paciente pac1 = new Paciente("44444444D", "444", "Paco", "Serrano",
                Date.valueOf("1991-03-01"), "Jesus@gmail.com", "111222333", "123456781");
        pacientes.add(pac1);

        pacientes.add(new Paciente("55555555E", "5", "Sofia", "Segovia",
                Date.valueOf("1990-05-01"), "Jesus@hotmail.com", "777999888", "123456782"));

        medicos.add(new Medico("66666666F", "6", "Joel", "García",
                Date.valueOf("1991-03-05"), "Pablo@yahoo.com", "987654321", null, 0, null));

        administrativos.add(new Administrativo("77777777F", "admin", "TEST", "TEST",
                Date.valueOf("1950-03-01"), "Jesus@hotmail.com", "777999888", 0, null));


    }

//Gestion Usuario ---------------------------------------------------------------------------------------------------------------------
    //Administrador
    public String anadirUsuario() {
        try {
            Integer.parseInt(dni.substring(0, 8));
            if (dni.equals("") || nombre.equals("") || apellidos.equals("") || telefono.equals("") || email.equals("") || contrasena.equals("")) {
                FacesContext ctx = FacesContext.getCurrentInstance();
                ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Faltan datos", "Faltan datos"));
            } else if (dni.length() > 9) {
                throw new RuntimeException();
            } else if ((dni.charAt(8) < 'A') || (dni.charAt(8) > 'Z')) {
                FacesContext ctx = FacesContext.getCurrentInstance();
                ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "DNI: Último caracter debe ser letra mayúscula",
                        "DNI: Último caracter debe ser letra mayúscula"));
            } else if (year < 1900 || year > 2200) {
                FacesContext ctx = FacesContext.getCurrentInstance();
                ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Año no válido", "Año no válido"));
            } else {
                switch (tipo) {
                    case "1":
                        pacientes.add(new Paciente(dni, contrasena, nombre, apellidos,
                                Date.valueOf(year + "/" + mes + "/" + dia), email, telefono, "132456780"));
                        break;
                    case "2":
                        medicos.add(new Medico(dni, contrasena, nombre, apellidos,
                                Date.valueOf(year + "/" + mes + "/" + dia), email, telefono, especialidad, numeroTrabajador, departamento));
                        break;
                    case "3":
                        administrativos.add(new Administrativo(dni, contrasena, nombre, apellidos,
                                Date.valueOf(year + "/" + mes + "/" + dia), email, telefono, numeroTrabajador, departamento));
                        break;
                    default:
                        FacesContext ctx = FacesContext.getCurrentInstance();
                        ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Seleccione Rol", "Seleccione Rol"));
                        break;
                }
            }
        } catch (RuntimeException e) {
            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "DNI: 8 digitos + letra mayúcula",
                    "DNI: 8 digitos + letra mayúcula"));
        }
        return null;
    }

    public String eliminarMedico(int i) {
        medicos.remove(i);
        return null;
    }

    public String eliminarPaciente(int i) {
        pacientes.remove(i);
        return null;
    }

    public String eliminarAdministrativo(int i) {
        administrativos.remove(i);
        return null;
    }
    //Gestion Lista de espera -----------------------------------------------------------------------------
    //Para Administrativo

    public String anadirListaEspera() {
        lista.add(new ListaDeEspera(nombreL));
        return null;
    }

    public String anadirPacienteLista(int i, int pos) {
        if (lista.get(i).getPaciente().contains(pacientes.get(pos))) {
            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ya existe en lista", "Ya existe en lista"));
        } else {
            lista.get(i).getPaciente().add(pacientes.get(pos));
        }
        return null;
    }

    public String eliminarPacienteLista(int i, int pos) {
        lista.get(i).getPaciente().remove(lista.get(i).getPaciente().get(pos));
        return null;
    }
    // Gestion Citas-----------------------------------------------------------------------------
    //Administrativo 

    public String anadirCita() {
        Cita c = new Cita(diaC, mesC - 1, yearC - 1900, horC, minC, lugar, motivo, urgente);
        if (yearC < 1900 || yearC > 2200) {
            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Fecha no válida", "Fecha no válida"));
        } else if (lugar.equals("") || motivo.equals("")) {
            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Faltan datos", "Faltan datos"));
        } else if (citas.contains(c)) {
            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Repetido", "Repetido"));
        } else {
            System.out.println(urgente);
            citas.add(c);
            medicos.get(indexMed()).getCita().add(c);
            pacientes.get(indexPac()).getCita().add(c);
            mdni.add(medicos.get(indexMed()).getDni());
            pdni.add(pacientes.get(indexPac()).getDni());
        }
        return null;
    }

    public int indexMed() {
        for (int i = 0; i < medicos.size(); i++) {
            if (medicos.get(i).equals(medicos.get(med))) {
                return i;
            }
        }
        return 0;
    }

    public int indexPac() {
        for (int i = 0; i < pacientes.size(); i++) {
            if (pacientes.get(i).equals(pacientes.get(pac))) {
                return i;
            }
        }
        return 0;
    }

    private int indexMedEli(String mdni) {
        for (int i = 0; i < medicos.size(); i++) {
            if (medicos.get(i).getDni().equals(mdni)) {
                return i;
            }
        }
        return 0;
    }

    private int indexMedCitaEli(Medico m, int j) {
        for (int i = 0; i < m.getCita().size(); i++) {
            if (m.getCita().get(i).equals(citas.get(j))) {
                return i;
            }
        }
        return 0;
    }

    public String eliminarCita(int i, String mdni) {
        Medico m = medicos.get(indexMedEli(mdni));
        int ind = indexMedCitaEli(m, i);
        m.getCita().remove(m.getCita().get(ind));
        citas.remove(i);
        this.mdni.remove(i);
        this.pdni.remove(i);
        return null;
    }
    // Gestion Paciente del médico--------------------------------------------------------

    //Médico
    public String añadirPaciente(int i) {
        if (medicos.get(indexMedico()).getPaciente_Consultor().contains(pacientes.get(i))) {
            FacesContext ctx = FacesContext.getCurrentInstance();
            ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ya existe en lista", "Ya existe en lista"));
        } else {
            medicos.get(indexMedico()).getPaciente_Consultor().add(pacientes.get(i));
        }
        return null;
    }

    public int indexMedico() {
        for (int i = 0; i < medicos.size(); i++) {
            if (usuarioMBean.getUsuario().getDni().equals(medicos.get(i).getDni())) {
                return i;
            }
        }
        return 0;
    }

    public int indexPaciente() {
        for (int i = 0; i < pacientes.size(); i++) {
            if (usuarioMBean.getUsuario().getDni().equals(pacientes.get(i).getDni())) {
                return i;
            }
        }
        return 0;
    }

    public String eliminarPacienteMedico(int i) {
        medicos.get(indexMedico()).getPaciente_Consultor().remove(i);
        return null;
    }

    public String rol(Usuario u) {
        return u.getClass().toString().substring(16, u.getClass().toString().length());
    }

    // Setters/Getters--------------------------------------------------------
    public String getNombreL() {
        return nombreL;
    }

    public void setNombreL(String nombreL) {
        this.nombreL = nombreL;
    }

    public List<ListaDeEspera> getLista() {
        return lista;
    }

    public void setLista(List<ListaDeEspera> lista) {
        this.lista = lista;
    }

    public String getDni() {
        return dni;
    }

    public void setDni(String dni) {
        this.dni = dni;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getContrasena() {
        return contrasena;
    }

    public void setContrasena(String contrasena) {
        this.contrasena = contrasena;
    }

    public String getApellidos() {
        return apellidos;
    }

    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMes() {
        return mes;
    }

    public void setMes(int mes) {
        this.mes = mes;
    }

    public int getDia() {
        return dia;
    }

    public void setDia(int dia) {
        this.dia = dia;
    }

    public Date getFecha() {
        return fecha;
    }

    public void setFecha(Date fecha) {
        this.fecha = fecha;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getTelefono() {
        return telefono;
    }

    public void setTelefono(String telefono) {
        this.telefono = telefono;
    }

    public String getTipo() {
        return tipo;
    }

    public void setTipo(String tipo) {
        this.tipo = tipo;
    }

    public List<Medico> getMedicos() {
        return medicos;
    }

    public void setMedicos(List<Medico> medicos) {
        this.medicos = medicos;
    }

    public List<Paciente> getPacientes() {
        return pacientes;
    }

    public void setPacientes(List<Paciente> pacientes) {
        this.pacientes = pacientes;
    }

    public List<Administrador> getAdministradores() {
        return administrador;
    }

    public void setAdministrador(List<Administrador> administrador) {
        this.administrador = administrador;
    }

    public int getListaE() {
        return listaE;
    }

    public void setListaE(int listaE) {
        this.listaE = listaE;
    }

    public List<Administrativo> getAdministrativos() {
        return administrativos;
    }

    public void setAdministrativos(List<Administrativo> administrativos) {
        this.administrativos = administrativos;
    }

    public String getEspecialidad() {
        return especialidad;
    }

    public void setEspecialidad(String especialidad) {
        this.especialidad = especialidad;
    }

    public int getNumeroTrabajador() {
        return numeroTrabajador;
    }

    public void setNumeroTrabajador(int numeroTrabajador) {
        this.numeroTrabajador = numeroTrabajador;
    }

    public String getDepartamento() {
        return departamento;
    }

    public void setDepartamento(String departamento) {
        this.departamento = departamento;
    }

    public int getYearC() {
        return yearC;
    }

    public void setYearC(int yearC) {
        this.yearC = yearC;
    }

    public int getMesC() {
        return mesC;
    }

    public void setMesC(int mesC) {
        this.mesC = mesC;
    }

    public int getDiaC() {
        return diaC;
    }

    public void setDiaC(int diaC) {
        this.diaC = diaC;
    }

    public int getHorC() {
        return horC;
    }

    public void setHorC(int horC) {
        this.horC = horC;
    }

    public int getMinC() {
        return minC;
    }

    public void setMinC(int minC) {
        this.minC = minC;
    }

    public String getLugar() {
        return lugar;
    }

    public void setLugar(String lugar) {
        this.lugar = lugar;
    }

    public String getMotivo() {
        return motivo;
    }

    public void setMotivo(String motivo) {
        this.motivo = motivo;
    }

    public boolean isUrgente() {
        return urgente;
    }

    public void setUrgente(boolean urgente) {
        this.urgente = urgente;
    }

    public List<Cita> getCitas() {
        return citas;
    }

    public void setCitas(List<Cita> citas) {
        this.citas = citas;
    }

    public int getMed() {
        return med;
    }

    public void setMed(int med) {
        this.med = med;
    }

    public int getPac() {
        return pac;
    }

    public void setPac(int pac) {
        this.pac = pac;
    }

    public List<String> getMdni() {
        return mdni;
    }

    public void setMdni(List<String> mdni) {
        this.mdni = mdni;
    }

    public List<String> getPdni() {
        return pdni;
    }

    public void setPdni(List<String> pdni) {
        this.pdni = pdni;
    }

    public static String loginPage() {
        return "login";
    }

    //DEMO
    public String autenticar() {
        FacesContext ctx = FacesContext.getCurrentInstance();
        //find user by DNI
        for (Medico u : medicos) {
            if (u.getDni().equals(dni)) {
                if (u.getPassword().equals(contrasena)) {
                    //user authorized -> redirect to home
                    usuarioMBean.setUsuario(u);
                    return usuarioMBean.home() + "?faces-redirect=true";
                } else {
                    //user found & password incorrect
                    ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                            "La contraseña no está corecta.", "La contraseña no está corecta."));
                    return null;
                }
            }
        }

        for (Paciente u : pacientes) {
            if (u.getDni().equals(dni)) {
                if (u.getPassword().equals(contrasena)) {
                    //user authorized -> redirect to home
                    usuarioMBean.setUsuario(u);
                    return usuarioMBean.home() + "?faces-redirect=true";
                } else {
                    //user found & password incorrect
                    ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                            "La contraseña no está corecta.", "La contraseña no está corecta."));
                    return null;
                }
            }
        }

        for (Administrativo u : administrativos) {
            if (u.getDni().equals(dni)) {
                if (u.getPassword().equals(contrasena)) {
                    //user authorized -> redirect to home
                    usuarioMBean.setUsuario(u);
                    return usuarioMBean.home() + "?faces-redirect=true";
                } else {
                    //user found & password incorrect
                    ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                            "La contraseña no está corecta.", "La contraseña no está corecta."));
                    return null;
                }
            }
        }

        for (Administrador u : administrador) {
            if (u.getDni().equals(dni)) {
                if (u.getPassword().equals(contrasena)) {
                    //user authorized -> redirect to home
                    usuarioMBean.setUsuario(u);
                    return usuarioMBean.home() + "?faces-redirect=true";
                } else {
                    //user found & password incorrect
                    ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                            "La contraseña no está corecta.", "La contraseña no está corecta."));
                    return null;
                }
            }
        }

        //user not found
        ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                "Usuario no encontrado.", "Usuario no encontrado."));
        return null;
    }

    public UsuarioMBean getUsuarioMBean() {
        return usuarioMBean;
    }

    public void setUsuarioMBean(UsuarioMBean usuarioMBean) {
        this.usuarioMBean = usuarioMBean;
    }

    public String logout() {
        FacesContext ctx = FacesContext.getCurrentInstance();
        ctx.getExternalContext().invalidateSession();
        return loginPage();
    }
    
    
}
